$E: null;
$B: null;
$namespace: 'my';
$element-separator: '__';
$modifier-separator: '--';
$state-prefix: 'is-';

@use 'sass:meta';
@use 'sass:string';

/* BEM support Func */
@function selectorToString($selector) {
	$selector: meta.inspect($selector);
	$selector: string.slice($selector, 2, -2);

	@return $selector;
}
// 判断 父级 是否包含'--'
@function containsModifier($selector) {
	$selector: selectortostring($selector);

	@if string.index($selector, $modifier-separator) {
		@return true;
	}

 @else {
		@return false;
	}
}
// 判断 父级 是否包含'.is-'
@function containWhenFlag($selector) {
	$selector: selectortostring($selector);

	@if string.index($selector, '.' + $state-prefix) {
		@return true;
	}

 @else {
		@return false;
	}
}
// 判断 父级 是否包含 ':'
@function containPseudoClass($selector) {
	$selector: selectortostring($selector);

	@if string.index($selector, ':') {
		@return true;
	}

 @else {
		@return false;
	}
}

@function hitAllSpecialNestRule($selector) {
	@return containsModifier($selector) or containWhenFlag($selector) or containPseudoClass($selector);
}

/* BEM
-------------------------- */
@mixin b($block) {
	$B: $namespace + '-' + $block !global; // 变量拼接形成对应格式的class；再使用!global将其提升为全局变量

	.#{$B} {
		@content; // 使用混合；大括号后定义的样式将都会解析到这里
	}
}
// 定义混合
@mixin e($element) {
	$E: $element !global;
	$selector: &;
	$currentSelector: '';

	@each $unit in $element {
		$currentSelector: #{$currentSelector + '.' + $B + $element-separator + $unit + ','};
	}

	@if hitAllSpecialNestRule($selector) {
		@at-root {
			#{$selector} {
				#{$currentSelector} {
					@content;
				}
			}
		}
	}

 @else {
		@at-root {
			#{$currentSelector} {
				@content;
			}
		}
	}
}

@mixin m($modifier) {
	$selector: &;
	$currentSelector: '';

	@each $unit in $modifier {
		$currentSelector: #{$currentSelector + & + $modifier-separator + $unit + ','};
	}

	@at-root {
		#{$currentSelector} {
			@content;
		}
	}
}

@mixin configurable-m($modifier, $E-flag: false) {
	$selector: &;
	$interpolation: '';

	@if $E-flag {
		$interpolation: $element-separator + $E-flag;
	}

	@at-root {
		#{$selector} {
			.#{$B + $interpolation + $modifier-separator + $modifier} {
				@content;
			}
		}
	}
}

@mixin spec-selector($specSelector: '', $element: $E, $modifier: false, $block: $B) {
	$modifierCombo: '';

	@if $modifier {
		$modifierCombo: $modifier-separator + $modifier;
	}

	@at-root {
		#{&}#{$specSelector}.#{$block + $element-separator + $element + $modifierCombo} {
			@content;
		}
	}
}

@mixin meb($modifier: false, $element: $E, $block: $B) {
	$selector: &;
	$modifierCombo: '';

	@if $modifier {
		$modifierCombo: $modifier-separator + $modifier;
	}

	@at-root {
		#{$selector} {
			.#{$block + $element-separator + $element + $modifierCombo} {
				@content;
			}
		}
	}
}

@mixin when($state) {
	@at-root {
		&.#{$state-prefix + $state} {
			@content;
		}
	}
}

@mixin extend-rule($name) {
	@extend #{'%shared-' + $name};
}

@mixin share-rule($name) {
	$rule-name: '%shared-' + $name;

	@at-root #{$rule-name} {
		@content;
	}
}

@mixin pseudo($pseudo) {
	@at-root #{&}#{':#{$pseudo}'} {
		@content;
	}
}
